package sueca2011;

import java.rmi.RemoteException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.Observable;
import java.util.Observer;

/**
 *
 * @author Renzo
 */
public class Rodada extends Observable implements Runnable{
    private ArrayList<Jogada> jogadas;
    private int indiceAtual;
    private Jogador jogadorVencedor;
    private Jogador ordem[];
    private Jogo jogo;
    private Carta puxada;

    public Rodada(Jogo jogo,Jogador ordem[]) throws RemoteException{
        this.jogo = jogo;
        jogadas = new ArrayList<Jogada>();
        this.setOrdem(ordem);
        this.puxada=null;
    }

    public Rodada(Jogo jogo){
        this.jogo = jogo;
        
        jogadas = new ArrayList<Jogada>();
        
    }

    public void setOrdem(Jogador ordem[]) throws RemoteException{
        if(ordem.length==4){
            this.ordem = ordem;
            for(int i=0;i<ordem.length;i++){
                System.out.println(ordem[i].getNome());
                if(ordem[i] instanceof IA)
                    this.adicionaObserver((IA)ordem[i]);
            }
        }
    }

    public void adicionaObserver(Observer ob){
        this.addObserver(ob);
    }

    public synchronized void run(){
        this.notifyObservers();
        this.setChanged();
        this.notifyObservers(new InicioRodada(this.ordem));
        this.setChanged();

        this.iniciar();

        int last=-1;
        try{
            while(!isFinalizada()){
                if(last!=indiceAtual && last>=0){
                    this.notifyObservers(new AlertaJogada(ordem[last].getUltimaJogada()));
                    this.setChanged();
                    try {
                        Thread.sleep(800);
                    } catch (InterruptedException ex) {
                        ex.printStackTrace();
                    }
                }
                last = indiceAtual;
                try {
                    System.out.println("JOGANDO: "+ordem[indiceAtual].getNome());
                    this.notifyObservers(new AlertaVez(ordem[indiceAtual]));
                    this.setChanged();
                    while (!ordem[indiceAtual].hasJogada()) {
                        if(ordem[indiceAtual] instanceof Humano)
                            Thread.sleep(500);
                        else
                            Thread.sleep(200);
                    }
                    System.out.println("Jogador "+ordem[indiceAtual].getNome()+" escolheu jogada!");
                    jogo.realizaJogada(ordem[indiceAtual]);
                    System.out.println("Jogo validou");

                } catch (InterruptedException ex) {
                    ex.printStackTrace();
                }
            }
            this.notifyObservers(new AlertaJogada(ordem[last].getUltimaJogada()));
            this.setChanged();
            System.out.println("Vencedor: "+this.jogadorVencedor.getNome());
            this.notifyObservers(new AlertaVencedor(this.getVencedor()));
            this.setChanged();
            try {
                Thread.sleep(3250);
            } catch (InterruptedException ex) {
                ex.printStackTrace();
            }
            this.notifyObservers(new FimRodada(this.getVencedor()));
            this.setChanged();
        }catch(RemoteException e){
           e.printStackTrace();
       }
    }

    private void iniciar(){
        this.indiceAtual = 0;
    }

    public void finalizar() throws RemoteException{
        if(!isFinalizada()){
            Jogada vencedora=null, j;
            Iterator<Jogada> it = jogadas.iterator();

            int pts=0;

            while(it.hasNext()){
                j = it.next();
                System.out.println("J "+j.getJogador().getNome());
                pts+=Jogo.valorCarta(j.getCartaJogada());
                if(vencedora==null)
                    vencedora = j;
                else{
                    if(vencedora.getCartaJogada().compareTo(this.jogo.getTrunfo().getNipe(),this.puxada.getNipe(), j.getCartaJogada())<0){
                        vencedora=j;
                    }
                }
            }
            jogadorVencedor = vencedora.getJogador();
            jogadorVencedor.getTime().adicionaPontos(pts);
            System.out.println(pts);
        }
    }

    public boolean realizaJogada(Jogada jogada) throws RemoteException{
        if(jogada.getJogador()==getJogadorAtual()){
            //Salva a jogada realizada
            jogadas.add(jogada);
            if (this.puxada == null){
                this.puxada=jogada.getCartaJogada();
            }
            //Dá a vez para o próximo jogador
            indiceAtual++;
            if(indiceAtual==ordem.length)
                this.finalizar();
            return true;
        }else
            return false;
    }

    public Jogador getJogadorAtual(){
        return this.ordem[indiceAtual];
    }

    public Carta getPuxadaAtual(){
        return this.puxada;
    }

    public Jogador getVencedor(){
        return jogadorVencedor;
    }

    public boolean isFinalizada(){
        return jogadorVencedor!=null;
    }
    
    public Jogo getJogo(){
        return jogo;
    }
}
